home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / role / larn.lha / tgetstr.c < prev    next >
C/C++ Source or Header  |  1995-11-19  |  7KB  |  288 lines

  1. /************************************************************************
  2.  *                                  *
  3.  *          Copyright (c) 1982, Fred Fish           *
  4.  *              All Rights Reserved             *
  5.  *                                  *
  6.  *  This software and/or documentation is released for public   *
  7.  *  distribution for personal, non-commercial use only.     *
  8.  *  Limited rights to use, modify, and redistribute are hereby  *
  9.  *  granted for non-commercial purposes, provided that all      *
  10.  *  copyright notices remain intact and all changes are clearly *
  11.  *  documented.  The author makes no warranty of any kind with  *
  12.  *  respect to this product and explicitly disclaims any implied    *
  13.  *  warranties of merchantability or fitness for any particular *
  14.  *  purpose.                            *
  15.  *                                  *
  16.  ************************************************************************
  17.  */
  18.  
  19.  
  20. /*
  21.  *  LIBRARY FUNCTION
  22.  *
  23.  *  tgetstr   extract string capability from termcap entry
  24.  *
  25.  *  KEY WORDS
  26.  *
  27.  *  termcap
  28.  *
  29.  *  SYNOPSIS
  30.  *
  31.  *  char *tgetstr(id,area)
  32.  *  char *id;
  33.  *  char **area;
  34.  *
  35.  *  DESCRIPTION
  36.  *
  37.  *  Gets the string capability for <id>, placing it in
  38.  *  the buffer at *area, and advancing *area to point
  39.  *  to next available storage.
  40.  *
  41.  *  For example, if the following capabilities are
  42.  *  in the termcap file:
  43.  *
  44.  *      ZZ=zzzz
  45.  *      YY=yyyyyy
  46.  *      WW=www
  47.  *
  48.  *  then successive calls using YY, ZZ, and WW will
  49.  *  build the following buffer:
  50.  *
  51.  *      yyyyyy0zzzz0www0
  52.  *
  53.  *  The first call will return a pointer to yyyyyy, the
  54.  *  second will return a pointer to zzzz and the third
  55.  *  will return a pointer to www.  Note that each
  56.  *  string is null terminated, as are all C strings.
  57.  *
  58.  *  Characters preceded by the carot character (\136)
  59.  *  are mapped into the corresponding control character.
  60.  *  For example, the two character sequence ^A becomes
  61.  *  a single control-A (\001) character.
  62.  *
  63.  *  The escape character is the normal C backslash and
  64.  *  the normal C escape sequences are recognized, along
  65.  *  with a special sequence for the ASCII escape character
  66.  *  (\033).  The recognized sequences are:
  67.  *
  68.  *      \E   =>  '\033'  (ASCII escape character)
  69.  *      \b   =>  '\010'  (ASCII backspace character)
  70.  *      \f   =>  '\014'  (ASCII form feed character)
  71.  *      \n   =>  '\012'  (ASCII newline/linefeed char)
  72.  *      \r   =>  '\015'  (ASCII carriage return char)
  73.  *      \t   =>  '\011'  (ASCII tab character)
  74.  *      \ddd =>  '\ddd'  (arbitrary ASCII digit)
  75.  *      \x   =>  'x'     (ordinary ASCII character)
  76.  *
  77.  */
  78.  
  79. #include <stdio.h>
  80. #include <ctype.h>
  81. #ifdef VMS
  82. # define index strchr
  83. #endif
  84. #ifdef ULTRIX
  85. # include <strings.h>
  86. #endif
  87.  
  88. extern char *_tcpbuf;       /* Termcap entry buffer pointer */
  89.  
  90. #ifdef MSDOS
  91.     extern char *index();
  92. #endif
  93.  
  94. /*
  95.  *  PSEUDO CODE
  96.  *
  97.  *  Begin tgetstr
  98.  *      Initialize pointer to the termcap entry buffer.
  99.  *      While there is a field to process
  100.  *      Skip over the field separator character.
  101.  *      If this is the entry we want then
  102.  *          If the entry is not a string then
  103.  *          Return NULL.
  104.  *          Else
  105.  *          Transfer string and rtn pointer.
  106.  *          End if
  107.  *      End if
  108.  *      End while
  109.  *      Return NULL
  110.  *  End tgetstr
  111.  *
  112.  */
  113.  
  114. char *tgetstr(id,area)
  115. char *id;
  116. char **area;
  117. {
  118.     char *bp;
  119.     char *decode();
  120.  
  121.     bp = _tcpbuf;
  122.     while ((bp = index(bp,':')) != NULL) {
  123.     bp++;
  124.     if (*bp++ == id[0] && *bp != NULL && *bp++ == id[1]) {
  125.         if (*bp != NULL && *bp++ != '=') {
  126.         return(NULL);
  127.         } else {
  128.         return(decode(bp,area));
  129.         }
  130.     }
  131.     }
  132.     return(NULL);
  133. }
  134.  
  135. /*
  136.  *  INTERNAL FUNCTION
  137.  *
  138.  *  decode   transfer string capability, decoding escapes
  139.  *
  140.  *  SYNOPSIS
  141.  *
  142.  *  static char *decode(bp,area)
  143.  *  char *bp;
  144.  *  char **area;
  145.  *
  146.  *  DESCRIPTION
  147.  *
  148.  *  Transfers the string capability, up to the next ':'
  149.  *  character, or null, to the buffer pointed to by
  150.  *  the pointer in *area.  Note that the initial
  151.  *  value of *area and *area is updated to point
  152.  *  to the next available location after the null
  153.  *  terminating the transfered string.
  154.  *
  155.  *  BUGS
  156.  *
  157.  *  There is no overflow checking done on the destination
  158.  *  buffer, so it better be large enough to hold
  159.  *  all expected strings.
  160.  *
  161.  */
  162.  
  163. /*
  164.  *  PSEUDO CODE
  165.  *
  166.  *  Begin decode
  167.  *      Initialize the transfer pointer.
  168.  *      While there is an input character left to process
  169.  *      Switch on input character
  170.  *      Case ESCAPE:
  171.  *          Decode and xfer the escaped sequence.
  172.  *          Break
  173.  *      Case CONTROLIFY:
  174.  *          Controlify and xfer the next character.
  175.  *          Advance the buffer pointer.
  176.  *          Break
  177.  *      Default:
  178.  *          Xfer a normal character.
  179.  *      End switch
  180.  *      End while
  181.  *      Null terminate the output string.
  182.  *      Remember where the output string starts.
  183.  *      Update the output buffer pointer.
  184.  *      Return pointer to the output string.
  185.  *  End decode
  186.  *
  187.  */
  188.  
  189. static char *decode(bp,area)
  190. char *bp;
  191. char **area;
  192. {
  193.     char *cp, *bgn;
  194.     char *do_esc();
  195.  
  196.     cp = *area;
  197.     while (*bp != NULL && *bp != ':') {
  198.     switch(*bp) {
  199.     case '\\':
  200.         bp = do_esc(cp++,++bp);
  201.         break;
  202.     case '^':
  203.         *cp++ = *++bp & 037;
  204.         bp++;
  205.         break;
  206.     default:
  207.         *cp++ = *bp++;
  208.         break;
  209.     }
  210.     }
  211.     *cp++ = (char) NULL;
  212.     bgn = *area;
  213.     *area = cp;
  214.     return(bgn);
  215. }
  216.  
  217. /*
  218.  *  INTERNAL FUNCTION
  219.  *
  220.  *  do_esc    process an escaped sequence
  221.  *
  222.  *  SYNOPSIS
  223.  *
  224.  *  char *do_esc(out,in);
  225.  *  char *out;
  226.  *  char *in;
  227.  *
  228.  *  DESCRIPTION
  229.  *
  230.  *  Processes an escape sequence pointed to by
  231.  *  in, transfering it to location pointed to
  232.  *  by out, and updating the pointer to in.
  233.  *
  234.  */
  235.  
  236. /*
  237.  *  PSEUDO CODE
  238.  *
  239.  *  Begin do_esc
  240.  *      If the first character is not a NULL then
  241.  *      If is a digit then
  242.  *          Set value to zero.
  243.  *          For up to 3 digits
  244.  *              Accumulate the sum.
  245.  *          End for
  246.  *          Transfer the sum.
  247.  *          Else if character is in remap list then
  248.  *          Transfer the remapped character.
  249.  *          Advance the input pointer once.
  250.  *          Else
  251.  *          Simply transfer the character.
  252.  *          End if
  253.  *      End if
  254.  *      Return updated input pointer.
  255.  *  End do_esc
  256.  *
  257.  */
  258.  
  259. static char *maplist = {
  260.     "E\033b\bf\fn\nr\rt\t"
  261. };
  262.  
  263. char *do_esc(out,in)
  264. char *out;
  265. char *in;
  266. {
  267.     int count;
  268.     char ch;
  269.     char *cp;
  270.  
  271.     if (*in != NULL) {
  272.     if (isdigit(*in)) {
  273.         ch = 0;
  274.         for (count = 0; count < 3 && isdigit(*in); in++) {
  275.          ch <<= 3;
  276.          ch |= (*in - '0');
  277.         }
  278.         *out++ = ch;
  279.     } else if ((cp = index(maplist,*in)) != NULL) {
  280.         *out++ = *++cp;
  281.         in++;
  282.     } else {
  283.         *out++ = *in++;
  284.     }
  285.     }
  286.     return(in);
  287. }
  288.